const express = require('express');
const path = require('path');
const os = require('os')
const ChildProcess = require('child_process');

const SerialPort = require('./serial')
const { PromisifyExec } = require('../lib')

const router = express.Router();

const devices = {}

var my_process = null


router.get('/bind', async function (req, res) {
    const mac = req.query['mac']
    const id = req.query['id']
    if (mac == undefined || id == undefined) {
        res.json({ code: -2, msg: 'mac或id未提供' })
        return
    }
    try {
        const out = await PromisifyExec(`sudo rfcomm bind ${id} ${mac}`)
        console.log(out)
        res.json({ code: 0, msg: 'OK' })
    } catch (error) {
        console.log(error)
        res.json({ code: -1, msg: 'Error' })
    }
})

router.get('/list', function (req, res) {
    SerialPort.listDevices().then(ports => {
        res.json(ports)
    })
})

router.get('/connect', function (req, res) {
    const name = req.query['name']
    const baudrate = parseInt(req.query['baudrate'])
    if (name == undefined) {
        res.json({ code: -2, msg: 'Error' })
        return
    }

    const device = devices[name]

    if (device && device.device && device.device.isOpen) {
        res.json({ code: -1, msg: 'Error' })
        return
    }

    try {
        devices[name] = new SerialPort(name, { baudRate: baudrate })
        res.json({ code: 0, msg: 'OK' })
    } catch (error) {
        console.log(error)
        res.json({ code: -1, msg: 'Error' })
    }
})

router.get('/disconnect', async function (req, res) {
    const name = req.query['name']
    const device = devices[name]
    if (!device) {
        res.json({ code: -2, msg: 'Error' })
        return
    }
    try {
        device.close()
        // const buf = await PromisifyExec(`sudo rfcomm release ${name}`)
        devices[name] = null
        // console.log(String(buf))
        res.json({ code: 0, msg: 'OK' })
    } catch (error) {
        console.log(error)
        res.json({ code: -1, msg: 'Error' })
    }
})

router.get('/connected', function (req, res) {
    const name = req.query['name']
    const device = devices[name]
    if (!device) {
        res.json({ code: -2, msg: 'Error' })
        return
    }
    try {
        if (device.device.isOpen)
            res.json({ code: 0, msg: 'OK' })
        else {
            res.json({ code: -3, msg: 'Error' })
        }
    } catch (error) {
        console.log(error)
        res.json({ code: -1, msg: 'Error', value: '' })
    }
})

router.get('/release', async function (req, res) {
    const name = req.query['name']
    const device = devices[name]
    if (!device) {
        res.json({ code: -2, msg: 'Error' })
        return
    }
    try {
        // device.close()
        const buf = await PromisifyExec(`sudo rfcomm release ${name}`)
        devices[name] = null
        console.log(String(buf))
        res.json({ code: 0, msg: 'OK' })
    } catch (error) {
        console.log(error)
        res.json({ code: -1, msg: 'Error' })
    }
})

router.get('/send', function (req, res) {
    const name = req.query['name']
    const data = req.query['data']
    const device = devices[name]
    if (!device) {
        res.json({ code: -2, msg: 'Error' })
        return
    }
    if (!device.device.isOpen) {
        res.json({ code: -3, msg: 'closed' })
        return
    }
    try {
        device.writeAndDrain(data, () => {
            console.log('send data ', data)
            res.json({ code: 0, msg: 'OK' })
        })
    } catch (error) {
        console.log(error)
        res.json({ code: -1, msg: 'Error' })
    }
})

router.post('/sendBytes', function (req, res) {
    console.log(req.body)
    const name = req.body['name']
    const data = JSON.parse(req.body['data'])
    const device = devices[name]
    if (!device) {
        res.json({ code: -2, msg: 'Error' })
        return
    }
    if (!device.device.isOpen) {
        res.json({ code: -3, msg: 'closed' })
        return
    }
    try {
        device.writeAndDrain(data, () => {
            console.log('send data ', data)
            res.json({ code: 0, msg: 'OK' })
        })
    } catch (error) {
        console.log(error)
        res.json({ code: -1, msg: 'Error' })
    }
})

router.get('/receive', function (req, res) {
    const count = req.query['count']
    const name = req.query['name']
    const device = devices[name]
    if (!device) {
        res.json({ code: -2, msg: 'Error' })
        return
    }
    if (!device.device.isOpen) {
        res.json({ code: -3, msg: 'closed' })
        return
    }
    try {
        var str = device.readString(count)
        res.json({ code: 0, len: str.length, value: str })
    } catch (error) {
        console.log(error)
        res.json({ code: -1, msg: 'Error', value: '' })
    }
})

router.get('/receiveBytes', function (req, res) {
    const count = req.query['count']
    const name = req.query['name']
    const device = devices[name]
    if (!device) {
        res.json({ code: -2, msg: 'Error' })
        return
    }
    if (!device.device.isOpen) {
        res.json({ code: -3, msg: 'closed' })
        return
    }
    try {
        var buffer = device.read(count)
        res.json({ code: 0, len: buffer.length, value: JSON.stringify(Array.from(buffer.values())) })
    } catch (error) {
        console.log(error)
        res.json({ code: -1, msg: 'Error', value: '[]' })
    }
})

router.get('/clearFlush', async function (req, res) {
    const name = req.query['name']
    const device = devices[name]
    if (!device) {
        res.json({ code: -2, msg: 'Error' })
        return
    }
    if (!device.device.isOpen) {
        res.json({ code: -3, msg: 'closed' })
        return
    }
    try {
        device.clearFlush()
        res.json({ code: 0, msg: 'OK' })
    } catch (error) {
        console.log(device, error)
        res.json({ code: -1, msg: 'Error' })
    }
})

router.get('/startListening', function (req, res) {
    if (my_process && my_process.exitCode == null && (!my_process.killed)) {
        res.json({ code: 0, msg: 'OK' })
        return
    }
    try {
        my_process = ChildProcess.spawn('sudo rfcomm watch hci0 > /tmp/rfcomm.log 2>&1', { shell: true })
        // my_process = ChildProcess.spawn('sudo rfcomm watch hci0',{shell:true,stdio:'inherit'})
        res.json({ code: 0, msg: 'OK' })
    } catch (error) {
        console.log(error)
        res.json({ code: -1, msg: 'Error', value: '' })
    }
})

router.get('/stopListening', async function (req, res) {
    try {
        const buf = await PromisifyExec(`sudo killall rfcomm`)
    } catch (error) {
        console.log(error)
    }

    if (my_process && !my_process.killed) {
        try {

            my_process.kill()
            res.json({ code: 0, msg: 'OK' })
        } catch (error) {
            console.log(error)
            res.json({ code: -1, msg: 'Error', value: '' })
        }
    } else {
        res.json({ code: -2, msg: 'Error' })
    }

})

module.exports = router